﻿namespace Pyramid.Hardware.Gates
{
	using System;
	using Pyramid.Utility;

	/// <summary>
	/// Represents a logic gate with a single input signal.
	/// </summary>
	public abstract class UnaryGate
		: Gate
	{
		private ILine _inputLine;
		private UnarySignalOperation _operation;

		protected UnaryGate(ILine inputLine, UnarySignalOperation operation)
		{
			_operation = operation;
			InputLine = inputLine;
		}

		public ILine InputLine
		{
			get
			{
				return _inputLine;
			}
			internal set
			{
				Validate.IsNotNull(value, "value");

				if (_inputLine != null)
					_inputLine.SignalChange -= new EventHandler<SignalChangeEventArgs>(_inputLine_SignalChange);

				_inputLine = value;

				_inputLine.SignalChange += new EventHandler<SignalChangeEventArgs>(_inputLine_SignalChange);

				UpdateSignal();
			}
		}

		private void _inputLine_SignalChange(object sender, SignalChangeEventArgs e)
		{
			UpdateSignal();
		}

		private void UpdateSignal()
		{
			SetSignal(_operation(_inputLine.Signal));
		}

		protected delegate Trivalent UnarySignalOperation(Trivalent operand);
	}
}
